package cn.itsource.basic.publicController;

import cn.hutool.core.util.StrUtil;
import cn.itsource.basic.exception.BusinessException;
import cn.itsource.basic.utils.AjaxResult;
import cn.itsource.basic.utils.StrUtils;
import cn.itsource.basic.utils.VerifyCodeUtils;
import cn.itsource.user.domain.User;
import cn.itsource.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/verifyCode")
public class VerifyCodeController {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;


    //前端生成key - 就用来传递到后端来保存或获取redis图形验证码
    @GetMapping("/image/{keyValue}")
    public AjaxResult image(@PathVariable("keyValue") String keyValue) {
        try {
            //1.调用工具类生成图形验证码
            String code = StrUtils.getComplexRandomString(4);
            //2.将keyValue 和图形验证码code 保存到redis，并设置过期时间为5分钟
            redisTemplate.opsForValue().set(keyValue, code, 5, TimeUnit.MINUTES);
            //3.调用工具类将图形验证码编码成base64的字符串
            String base64Str = VerifyCodeUtils.verifyCode(115, 40, code);
            //4.把编码base64的字符串设置到AjaxResult中的obj
            return AjaxResult.me().setObj(base64Str);
        } catch (Exception e) {
            e.printStackTrace();
            return new AjaxResult(false, "获取图形验证码失败");
        }
    }

    //手机注册发送验证码接口
    @PostMapping("/smsCode")
    public AjaxResult smsCode(@RequestBody Map<String, String> map) {
        String phone = map.get("phone");
        String imageCode = map.get("imageCode");
        String imageCodeKey = map.get("imageCodeKey");
        //一：校验
        //1.1.空值校验 - hutools
        if (StrUtil.isBlank(phone) || StrUtil.isBlank(imageCode)
                || StrUtil.isBlank(imageCodeKey)) {
            throw new BusinessException("请把信息填写完整");
        }
        //1.2.图形验证码校验 - 是否过期 - 判断redis有没有
        Object imageValue = redisTemplate.opsForValue().get(imageCodeKey);//5649
        if (imageValue == null) {
            throw new BusinessException("图形验证码已过期请重新刷新");
        }
        //1.3.图形验证码校验 - 是否正确 - redis中的与页面传递过来的 - 忽略大小写
        if (!imageValue.toString().equalsIgnoreCase(imageCode)) {
            throw new BusinessException("图形验证码输入错误");
        }
        //1.4：手机号码是否注册过
        User user = userMapper.findPhone(phone);
        if (user != null) {
            throw new BusinessException("你输入的电话号已被注册");
        }

        //二：获取手机短信验证码 - 获取redis的手机短信验证码【register:18455669988 - 764347:1715413642524】
        Object smsCodeObj = redisTemplate.opsForValue().get("register:" + phone); //764347:1715413642524
        System.out.println(smsCodeObj + "手机短信验证码");
        String code = null;
        if (smsCodeObj == null) {
            code = StrUtils.getRandomString(6);
        } else {
            //2.1.如果没有：要么时第一次发送，要么就过期了 - 直接使用工具类直接生成新的短信验证码 764347[0]
            // 1715413642524[1]
            Long oldTime = Long.parseLong(smsCodeObj.toString().split(":")[1]);
            //2.2.如果有：没有过期 => 判断重发时间【使用当前系统时间-redis存的时间】
            //a.<=1分钟 = 违规操作 => 抛异常 - 操作过于频繁，请稍后重试
            if ((System.currentTimeMillis() - oldTime) <= 1 * 60 * 1000) {
                throw new BusinessException("重复获取短信验证码，请稍后再试");
            } else {
                //b.>1分钟 = 可以重发 就用之前没有过期的验证码9527
                code = smsCodeObj.toString().split(":")[0];
            }
        }

        //三：将验证码以【register:18455669988 - 9527:121221121212】再存一次。重新设置过期时间为3分钟
        redisTemplate.opsForValue().set("register:" + phone,code+":"+System.currentTimeMillis()
                ,3,TimeUnit.MINUTES);

        //四：调用工具类发送手机短线验证码
        //SmsUtils.sendSms(phone,"你的手机验证码是：" + code +",请在3分钟内使用!!!");
        System.out.println("你的手机验证码是：" + code +",请在3分钟内使用!!!");
        return new AjaxResult();
    }

    //微信扫描成功之后绑定手机号接口
    @PostMapping("/binderSmsCode")
    public AjaxResult binderSmsCode(@RequestBody Map<String, String> map) {
        String phone = map.get("phone");

        //一：校验
        //1.1.空值校验 - hutools
        if (StrUtil.isBlank(phone)) {
            throw new BusinessException("请把信息填写完整");
        }

        //二：获取手机短信验证码 - 获取redis的手机短信验证码【register:18455669988 - 764347:1715413642524】
        Object smsCodeObj = redisTemplate.opsForValue().get("binder:" + phone); //764347:1715413642524
        System.out.println(smsCodeObj + "手机短信验证码");
        String code = null;
        if (smsCodeObj == null) {
            code = StrUtils.getRandomString(6);  //生产手机验证码
        } else {
            //2.1.如果没有：要么时第一次发送，要么就过期了 - 直接使用工具类直接生成新的短信验证码 764347[0]
            // 1715413642524[1]
            Long oldTime = Long.parseLong(smsCodeObj.toString().split(":")[1]);
            //2.2.如果有：没有过期 => 判断重发时间【使用当前系统时间-redis存的时间】
            //a.<=1分钟 = 违规操作 => 抛异常 - 操作过于频繁，请稍后重试
            if ((System.currentTimeMillis() - oldTime) <= 1 * 60 * 1000) {
                throw new BusinessException("重复获取短信验证码，请稍后再试");
            } else {
                //b.>1分钟 = 可以重发 就用之前没有过期的验证码9527
                code = smsCodeObj.toString().split(":")[0];
            }
        }

        //三：将验证码以【register:18455669988 - 9527:121221121212】再存一次。重新设置过期时间为3分钟
        redisTemplate.opsForValue().set("binder:" + phone,code+":"+System.currentTimeMillis()
                ,3,TimeUnit.MINUTES);

        //四：调用工具类发送手机短线验证码
        //SmsUtils.sendSms(phone,"你的手机验证码是：" + code +",请在3分钟内使用!!!");
        System.out.println("你的手机验证码是：" + code +",请在3分钟内使用!!!");
        return new AjaxResult();
    }
}
